package com.china08.yxyapi.util;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;

/**
 * 
 * mongodb查询工具
 * 
 * @author JS-08
 *
 */
@Component
public class MongodbUtil {

    /**
     * 查询mongodb数据库 返回ids
     * 
     * @param dbc
     *            mongodtemplate 获得的连接(防止一个项目配置多个数据源)
     * @param db
     *            查询条件 没有就传NUll
     * @return
     */
    public static List<String> getListIds(DBCollection dbc, BasicDBObject db) {
        Assert.notNull(dbc, "请指定数据库连接");
        List<String> list = new ArrayList<String>();
        DBCursor cursor = null;
        cursor = dbc.find(db);
        try {
            if (cursor != null) {
                while (cursor.hasNext()) {
                    DBObject dBObject = cursor.next();
                    list.add(dBObject.get("_id").toString());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            cursor.close();
        }
        return list;
    }

    /**
     * 查询mongodb数据库全部 只适合Model里没有List字段的查询
     * 
     * @param dbc
     *            mongodtemplate 获得的连接(防止一个项目配置多个数据源)
     * @param db
     *            查询条件 没有就传NUll
     * @param entityClass
     *            此处为返回类型 , *并不是查询的类型, 查询的类型在获取数据库dbc的时候,已经指定.(如果是自己创建的model, id
     *            需为 _id)
     * @return List<T>
     */
    public static <T> List<T> getList(DBCollection dbc, BasicDBObject db, Class<T> entityClass) {
        Assert.notNull(dbc, "请指定数据库连接");
        Assert.notNull(entityClass, "请指定返回类型");
        List<T> list = new ArrayList<T>();
        DBCursor cursor = null;
        cursor = dbc.find(db);
        try {
            if (cursor != null) {
                while (cursor.hasNext()) {
                    DBObject dBObject = cursor.next();
                    T entity = entityClass.newInstance();
                    BeanUtils.copyProperties(entity, dBObject);
                    list.add(entity);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            cursor.close();
        }
        return list;
    }

    /**
     * 分页获取数据mongodb 只适合Model里没有List字段的查询
     * 
     * @param dbc
     *            mongodtemplate 获得的连接(防止一个项目配置多个数据源)
     * @param db
     *            查询条件 没有就传NUll
     * @param pageable
     *            分页工具 PageNum 从0开始
     * @param entityClass
     *            此处为返回类型 , ***并不是查询的类型, 查询的类型在获取数据库dbc的时候,已经指定. (如果是自己创建的model,
     *            id 需为 _id)
     * @return Page<T>
     */
    public static <T> Page<T> getPage(DBCollection dbc, BasicDBObject db, Pageable pageable, Class<T> entityClass) {
        Assert.notNull(dbc, "请指定数据库连接");
        Assert.notNull(entityClass, "请指定返回类型");
        Assert.notNull(pageable, "请指定查询索引位置");
        Page<T> page = null;
        List<T> list = new ArrayList<T>();
        DBCursor cursor = null;
        BasicDBObject orderDBObject = new BasicDBObject();
        Sort sort = pageable.getSort();
        for (Order order : sort) {
            orderDBObject.put(order.getProperty(), getOrder(order.getDirection()));
        }
        cursor = dbc.find(db).skip((pageable.getPageNumber() + 1 - 1) * pageable.getPageSize())
                .limit(pageable.getPageSize()).sort(orderDBObject);
        try {
            if (cursor != null) {
                while (cursor.hasNext()) {
                    DBObject dBObject = cursor.next();
                    T entity = entityClass.newInstance();
                    BeanUtils.copyProperties(entity, dBObject);
                    list.add(entity);
                }
            }
            if (list.size() > 0) {
                long countAll = dbc.count(db);
                page = new PageImpl<>(list, pageable, countAll);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            cursor.close();
        }
        if (page == null) {
            List<T> emptyList = new ArrayList<T>();
            page = new PageImpl<T>(emptyList, pageable, 0);
        }
        return page;
    }

    /**
     * 获取排序
     * 
     * @param order
     * @return
     */
    public static Integer getOrder(Direction order) {
        Integer orderInt = 0;
        if (Direction.DESC == order) {
            orderInt = -1;
        } else {
            orderInt = 1;
        }
        return orderInt;
    }

}
